iT邦幫忙

2025 iThome 鐵人賽

DAY 27
0
自我挑戰組

請問這是魔法嗎?前端轉職菜雞的修煉之路!系列 第 27

DAY 27 瀏覽目錄的魔法 - Hoisting (1) - var、let、const

  • 分享至 

  • xImage
  •  

Hoisting 這個觀念第一次聽到的時候,真是有聽沒有懂,直到再次面試前,才再次梳理這個觀念:

首先我們要先知道,Javascript 執行環境的三個階段:

  1. 創建期 (Creation Phase):
    這個時期,JS 引擎會先掃描整個程式碼,為當前執行環境建立所需的記憶體空間。
    簡單來說,就是在程式正式執行前,先找出所有的變數與函式宣告,並在記憶體中「預先登記」它們,就像閱讀一本書前先瀏覽目錄一樣。

    • 使用 var 宣告的變數,會被配置記憶體並自動初始化值為 undefined。
    • 使用 let 宣告的變數,只會被登記名稱但尚未初始化,在正式執行到該行前,會處於所謂的「暫時性死區(Temporal Dead Zone, TDZ)」中。
    • 使用 const 宣告的常數,與 let 類似,也會被登記但不會初始化;不同的是,const 在初始化時必須同時賦值,否則會拋出錯誤。
  2. 執行期 (Execution Phase):
    這個階段,JS 引擎會正式從上到下逐行執行程式碼。

    • var 變數會被賦予實際的值(覆蓋掉原本的 undefined)。
    • let 和 const 變數會在執行到宣告那一行時才被初始化,才能開始使用。
  3. 銷毀期 (Garbage Collection):
    當程式執行完畢,或變數不再被使用時,JS 會自動回收不再需要的記憶體空間。
    換句話說,只要一個變數或物件沒有被任何地方引用,引擎就會把它從記憶體中清除,釋放空間給其他程式使用。這個過程是自動進行的,不需要手動釋放記憶體。

知道這些觀念後,我們來看範例,跟著以上觀念一步步釐清:

  1. var 的 Hoisting

    console.log(a);
    var a = 10;
    console.log(a);
    

    a. 創建期:JS 先掃描程式碼,發現 var a。為 a 配置記憶體,並自動初始化為 undefined。
    b. 執行期:

    • 執行第一行:console.log(a) → 讀取 a,值是 undefined(因為還沒賦值)。
    • 執行第二行:a = 10 → 將值 10 寫入 a。
    • 執行第三行:console.log(a) → 讀取 a,值是 10。
  2. let 和 const 的 Hoisting

    console.log(b);
    let b = 20;
    

    a. 創建期:JS 先掃描程式碼,發現 let b。為 b 配置記憶體,但不初始化值,變數處於暫時性死區 (TDZ)。
    b. 執行期:

    • 執行 console.log(b) → 變數還沒初始化,為TDZ → ReferenceError
    • 執行 b = 20 → 才初始化並賦值
      所以打印出來的會是 ReferenceError: Cannot access 'b' before initialization
    console.log(c); 
    const c = 30;
    

    a. 創建期:JS 先掃描程式碼,發現 const c。為 c 配置記憶體,但不初始化值,變數處於暫時性死區 (TDZ)。
    b. 執行期:

    • 執行console.log(c) → 變數還沒初始化,為TDZ → ReferenceError
    • const c = 30 → 才初始化並賦值(如果宣告時沒有立即賦值,會直接 SyntaxError,而不是 ReferenceError。)
      所以打印出來的會是 ReferenceError: Cannot access 'c' before initialization

上一篇
DAY 26 偷偷雇一個地精的魔法 - Web Workers
下一篇
DAY 28 瀏覽目錄的魔法 - Hoisting (2) - function
系列文
請問這是魔法嗎?前端轉職菜雞的修煉之路!30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言